/**
 * ref:
 * 1. Server Sent Events (SSE) Streams with Node and Koa,
 *      https://medium.com/trabe/server-sent-events-sse-streams-with-node-and-koa-d9330677f0bf
 * 2. 从export视角对比esm与cjs, https://www.pipipi.net/21680.html/amp
 */

import Koa from 'koa'
import Router from 'koa-router';
import {PassThrough} from 'stream'

class Server {
    stream // = new PassThrough();

    constructor() {
        const router = new Router()
        router.get('/sse', async (ctx, next) => {
            // ctx.request.socket.setTimeout(0);
            // ctx.req.socket.setNoDelay(true);
            // ctx.req.socket.setKeepAlive(true);

            ctx.set({
                'Content-Type': 'text/event-stream',
                'Cache-Control': 'no-cache',
                'Connection': 'keep-alive',
            });

            this.stream = new PassThrough();
            ctx.status = 200;
            ctx.body = this.stream;

            const interval = setInterval(this.#emit, 1000);

            // this.stream.on('close', () => clearInterval(interval));
        })

        new Koa()
            .use(router.routes())
            .listen(8080, () => console.log('Listening on http://localhost:8080/sse'));
    }

    /**
     *  注意，回调函数使用`箭头函数`和`函数`的区别，
     *  在这里，#emit 将作为回调函数被使用，不能将其作为类的普通函数进行定义，
     *  因为这里用到了`this.`，在实际被回调时会发现`this`未定义。
     */
    #emit = () => {
        console.log('stream.write ...')
        this.stream.write(`data: ${new Date()}\n\n`)
        // ctx.body = `data: ${new Date()}\n\n`
    }
}

new Server();
